<?php

/**
 * 换关键词链接
 * Class Content
 */
class Content {

    /**
     * 匹配过的关键词MD5() [限制匹配次数]
     */
    public static $md_key = [];

    /**
     * 文本
     * 
     * @var string
     */
    protected $_content;

    /**
     * 关键词
     * 
     * @var string
     */
    protected $_keyword;

    /**
     * 限制字数
     *
     * @var int
     */
    protected $num;

    /**
     * 构造方法
     * 
     * @param string $content   文本内容
     * @param array $keyword   关键词
     * @param int   $num       限制文本配置关键词个数
     */
    public function __construct($content, $keyword, $num=2) {
        $this->setContent($content);
        $this->setKeyword($keyword);
        $this->num = $num;
        self::$md_key = array();
    }

    /**
     * 给关键词加上链接
     * 
     * @return string 
     */
    public function addKeywordLink() {
        //获取内容
        $content = $this->getContent();
        //获取关键词并进行长度排序(降序)
        $keywordArray = $this->sortKeywordArray($this->getKeyword());
        //获取所有的html标签(数组)
        $htmlTagArray = $this->getAllHtmlTag($content);
        //切割标签获取内容(数组)
        $noTagContentArray = $this->splitContentByHtmlTag($content);

        /**
          这边定义了一个临时数组
          $tempReplaceArray[1]用来存储所有关键词的正则表达式
          $tempReplaceArray[2]用来存储关键词的md5值
          $tempReplaceArray[3]用来存储需要替换的带链接的关键词
         */
        $tempReplaceArray = array();
        $tempReplaceArray[1] = array();
        $tempReplaceArray[2] = array();
        $tempReplaceArray[3] = array();

        foreach ($keywordArray as $keyword) {
            //preg_quote()  转义字符串中一些php正则字符 i 匹配大小写自摸
            $tempReplaceArray[1][] = '/' . preg_quote($keyword[0]) . '/i';
            $tempReplaceArray[2][] = '{' . md5($keyword[0]) . '}';
            $tempReplaceArray[3][] = '<a href="' . $keyword[1] . '" target="_blank">' . $keyword[0] . '</a>';
        }

        //循环替换每一段内容
        foreach ($noTagContentArray as $key => $noTagIntro) {
            //如果是空内容，则直接进行下一步
            if (!trim($noTagIntro)) {
                continue;
            }
            foreach ($tempReplaceArray[1] as $k=>$v){
                //&& !in_array($v,self::$md_key)
                //数组里面各个值的个数
                $arr_num = array_count_values(self::$md_key);
                if(preg_match($v,$noTagIntro) && @$arr_num[$v]<$this->num){
                    $noTagIntro = preg_replace($v, $tempReplaceArray[2][$k], $noTagIntro,1);  //把所有关键词替换成md5
                    array_push(self::$md_key,$v);
                }
            }
            $noTagIntro = str_replace($tempReplaceArray[2], $tempReplaceArray[3], $noTagIntro);   //把所有md5替换成关键词
            $noTagContentArray[$key] = $noTagIntro;
        }


        //组合提取的html标签和处理后的内容
        $finalContentArray = array();
        $count = count($noTagContentArray);
        for ($i = 0; $i < $count; $i++) {
            $finalContentArray[] = $noTagContentArray[$i];
            if (isset($htmlTagArray[$i])) {
                $finalContentArray[] = $htmlTagArray[$i];
            }
        }

        return implode('', $finalContentArray);
    }

    /**
     * 对关键词进行排序，最长的排前面
     * @param array $keywordArray
     * @return array $keywordArray
     */
    public function sortKeywordArray($keywordArray) {
        usort($keywordArray, function($a, $b) {
                    $al = strlen($a[0]);
                    $bl = strlen($b[0]);
                    if ($al == $bl)
                        return 0;
                    return ($al > $bl) ? -1 : 1;
                });
        return $keywordArray;
    }

    /**
     * 提取出所有html标签
     * 
     * @param string $content
     * @return array
     */
    public function getAllHtmlTag($content) {
        preg_match_all('/<\/?[a-zA-Z]+[^>]*>/', $content, $match);
        if (isset($match[0])) {
            $htmlTagArray = $match[0];
            return $htmlTagArray;
        }
        return array();
    }

    /**
     * 根据html标签切割内容
     * 
     * @param string $content
     * @return array
     */
    public function splitContentByHtmlTag($content) {
        $noTagContentArray = preg_split('/<\/?[a-zA-Z]+[^>]*>/', $content);
        return $noTagContentArray;
    }

    /**
     * 设置关键词
     * 
     * @param string $keyword
     */
    public function setKeyword($keyword) {
        $this->_keyword = $keyword;
    }

    /**
     * 获取关键词
     * 
     * @return string
     */
    public function getKeyword() {
        return $this->_keyword;
    }

    /**
     * 设置内容
     * 
     * @param string $content
     */
    public function setContent($content) {
        $this->_content = $content;
    }

    /**
     * 获取内容
     * 
     * @return string
     */
    public function getContent() {
        return $this->_content;
    }

}